home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 65.2 KB | 2,163 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UCalcCells.cp
- // Copyright © 1986-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UCALCCELL__
- #include "UCalcCells.h"
- #endif
-
- // Calc
-
- #ifndef __UCALC__
- #include "UCalc.h"
- #endif
-
- #ifndef __UCALCCOLUMNS__
- #include "UCalcColumns.h"
- #endif
-
- #ifndef __UCALCROWS__
- #include "UCalcRows.h"
- #endif
-
- // MacApp
-
- // Toolbox
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __QUICKDRAW__
- #include <Quickdraw.h>
- #endif
-
- // ANSI
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- #ifndef __STDLIB__
- #include <stdlib.h>
- #endif
-
-
- //========================================================================================
- // Global Functions
- //========================================================================================
- static CompareResult CompareCells(TObject* anItem, void* staticLink);
-
- //========================================================================================
- // struct CCellComparer
- //========================================================================================
-
- struct CCellComparer
- {
- public:
- RowNumber& r;
- ColumnNumber& c;
-
- // Constructor
- CCellComparer(RowNumber& theRow,
- ColumnNumber& theColumn) :
- r(theRow),
- c(theColumn)
- {
- }
- };
-
-
- //----------------------------------------------------------------------------------------
- // CompareCells:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- CompareResult CompareCells(TObject* anItem, void* staticLink)
- {
- CCellComparer* comparisonInfo = (CCellComparer*)staticLink;
-
- if (((TCell*)anItem)->fRow > comparisonInfo->r)
- return kItemGreaterThanCriteria;
- else if (((TCell*)anItem)->fRow < comparisonInfo->r)
- return kItemLessThanCriteria;
- else
- {
- if (((TCell*)anItem)->fColumn > comparisonInfo->c)
- return kItemGreaterThanCriteria;
- else if (((TCell*)anItem)->fColumn < comparisonInfo->c)
- return kItemLessThanCriteria;
- else
- return kItemEqualCriteria;
- }
- } // CompareCells
-
-
- //========================================================================================
- // CLASS TCellList
- //========================================================================================
- #undef Inherited
- #define Inherited TList
-
- #pragma segment ClassDescRes
- MA_DEFINE_CLASS_M1(TCellList, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TCellList destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- TCellList::~TCellList()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // TCellList::ICellList:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCellList::ICellList()
- {
- this->ISortedList();
- } // TCellList::ICellList
-
-
- //----------------------------------------------------------------------------------------
- // TCellList::Compare:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- CompareResult TCellList::Compare(TObject* item1,
- TObject* item2) // override
- {
- // since this is a cell list and we make sure that everything in it are cells, we
- // can typecast freely without side effects of insomnia
-
- // row is more important than column when ordering cells
- if (((TCell *)(item1))->fRow > ((TCell *)(item2))->fRow)
- return kItem1GreaterThanItem2;
- else if (((TCell *)(item1))->fRow < ((TCell *)(item2))->fRow)
- return kItem1LessThanItem2;
- else
- { // same row, must check column instead
- if (((TCell *)(item1))->fColumn > ((TCell *)(item2))->fColumn)
- return kItem1GreaterThanItem2;
- else if (((TCell *)(item1))->fColumn < ((TCell *)(item2))->fColumn)
- return kItem1LessThanItem2;
- else
- return kItem1EqualItem2;
- }
- } // TCellList::Compare
-
-
- //----------------------------------------------------------------------------------------
- // TCellList::GetCell:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- TCell* TCellList::GetCell(RowNumber r,
- ColumnNumber c)
- {
- CCellComparer aCellComparer(r, c);
- ArrayIndex index;
-
- return (TCell*)this->DoSearch(&::CompareCells, &aCellComparer, index);
- } // TCellList::GetCell
-
-
- //========================================================================================
- // CLASS TCell
- //========================================================================================
- #undef Inherited
- #define Inherited TObject
-
- #pragma segment ClassDescRes
- MA_DEFINE_CLASS_M1(TCell, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TCell constructor
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- TCell::TCell() :
- fCalcDocument(NULL),
- fDeleted(FALSE),
-
- fKind(kEmptyCell),
- fError(kNoError),
- fValue(0),
-
- fRow(0),
- fColumn(0),
- fEvaluating(FALSE),
-
- fMarked(FALSE)
- {
- FailMemError();
- } // TCell::TCell
-
-
- //----------------------------------------------------------------------------------------
- // TCell::ICell:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::ICell(TCalcDocument* owningDocument,
- RowNumber r,
- ColumnNumber c)
-
- {
- this->IObject();
-
- fCalcDocument = owningDocument;
-
- fRow = r;
- fColumn = c;
- } // TCell::ICell
-
-
- //----------------------------------------------------------------------------------------
- // TCell::Clone:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- TObject* TCell::Clone() // override
-
- {
- TCell * clonedCell;
-
-
- clonedCell = (TCell *)(Inherited::Clone());
- return (TObject *)(clonedCell);
- } // TCell::Clone
-
-
- //----------------------------------------------------------------------------------------
- // TCell::CopyContents:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::CopyContents(TCell* sourceCell)
-
- {
- fKind = sourceCell->fKind;
- fFormula = sourceCell->fFormula;
- } // TCell::CopyContents
-
-
- //----------------------------------------------------------------------------------------
- // TCell::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- TCell::~TCell()
-
- {
- } // TCell::Free
-
-
- //----------------------------------------------------------------------------------------
- // TCell::EvaluateFormula:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::EvaluateFormula(Boolean updateDependencies, Boolean& cellChanged)
-
- {
- KindOfCell theKind = kEmptyCell;
- EvalResult theError = kNoError;
- ValueType theValue = 0;
-
- if (updateDependencies)
- {
- // Use nesting to conserve stack space -- the iterator is destroyed before
- // we get here, so the parser and CStr255 can be allocated in its place!!
-
- CReferencedCellIterator iter(this);
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- aCell->RemoveDependentCell(this);
- }
-
- fValueString.Empty();
-
- fEvaluating = TRUE; // prevent self reference loop
-
- { // Use nesting to conserve stack space --
- // the iterator is destroyed before we get
- // here, so the parser can be allocated in
- // its place!!
- CCellParser theParser(this);
-
- theParser.EvaluateFormula(theKind, theError, theValue, fFormula, updateDependencies);
- }
-
- fEvaluating = FALSE;
-
- cellChanged = (theValue != fValue) || (theKind != fKind);
- if (cellChanged)
- {
- fCalcDocument->SetChangeCount(Max(fCalcDocument->fChangeCount + 1, 1));
- if ((theError == kNoError) || (theError == kGarbageAtEnd))
- fValue = theValue;
- fKind = theKind;
- this->invalidate();
- }
- } // TCell::EvaluateFormula
-
-
- //----------------------------------------------------------------------------------------
- // TCell::GetAsString:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::GetAsString(CStr255& theString)
-
- {
- theString = fFormula;
- } // TCell::GetAsString
-
-
- //----------------------------------------------------------------------------------------
- // TCell::GetValueAsString:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::GetValueAsString(CStr255& theString)
-
- {
- theString.Empty();
- switch (fKind)
- {
- case kTextCell:
- theString = fFormula;
- break;
-
- case kValueCell:
- if (fValueString.IsEmpty())
- this->ValueToString();
- theString = fValueString;
- break;
-
- case kErrorCell:
- NumToString(fError, theString);
- theString = "**ERROR " + theString;
- break;
-
- }
- } // TCell::GetValueAsString
-
-
- //----------------------------------------------------------------------------------------
- // TCell::GetCoordinates: Returns a CPoint describing the Cell's location on the GridView
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- CPoint TCell::GetCoordinates()
- {
- return CPoint(fColumn, fRow);
- } // TCell::GetCoordinates
-
-
- //----------------------------------------------------------------------------------------
- // TCell::invalidate:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::invalidate()
- {
- GridCell aCell;
-
-
- if ((fCalcDocument != NULL) && (fCalcDocument->fCellsView != NULL))
- {
- aCell.h = fColumn;
- aCell.v = fRow;
- fCalcDocument->fCellsView->InvalidateCell(aCell);
- }
- } // TCell::invalidate
-
-
- //----------------------------------------------------------------------------------------
- // TCell::IsEmpty:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- Boolean TCell::IsEmpty()
-
- {
- return (fKind == kEmptyCell) && (fFormula.Length() == 0);
- } // TCell::IsEmpty
-
-
- //----------------------------------------------------------------------------------------
- // TCell::SetDeleteState:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::SetDeleteState(Boolean deleted)
-
- {
- fDeleted = deleted;
- } // TCell::SetDeleteState
-
-
- //----------------------------------------------------------------------------------------
- // TCell::SetToString:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::SetToString(const CStr255& theString)
-
- {
- CStr255 theOldString;
-
- this->GetAsString(theOldString);
- if (CompareStrings(theString, theOldString) != 0)
- {
- fFormula = theString;
- fKind = kEmptyCell; // Force Recalculate to invalidate the cell
- this->Recalculate(!kForceAutomatic, kUpdateDependencies);// we want to set new dependents
-
- //!!!RCR Changed(0, fCalcDocument);
- }
- } // TCell::SetToString
-
-
- //----------------------------------------------------------------------------------------
- // TCell::Recalculate:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::Recalculate(Boolean forceAutomatic, Boolean updateDependencies)
-
- {
- Boolean cellChanged;
-
- this->EvaluateFormula(updateDependencies, cellChanged);
- if (cellChanged && (forceAutomatic || fCalcDocument->IsAutoCalc()))
- this->Changed(mValueChanged, this);
- } // TCell::Recalculate
-
- //----------------------------------------------------------------------------------------
- // TCell::GetDependencySpace:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- TDependencySpace* TCell::GetDependencySpace() // Override
-
- {
- return fCalcDocument->fDependencies;
- } // TCell::GetDependencySpace
-
- //----------------------------------------------------------------------------------------
- // TCell::DoUpdate:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
- void TCell::DoUpdate(ChangeID theChange,
- TObject* changedObject,
- TObject* changedBy,
- TDependencySpace* dependencySpace) // override
-
- {
- Boolean cellChanged;
-
- if (theChange == mValueChanged)
- {
- this->EvaluateFormula(!kUpdateDependencies, cellChanged);
- if (!cellChanged)
- theChange = kNoChange;
- }
- else if (theChange == mWidthChanged)
- theChange = kNoChange;
- else
- Inherited::DoUpdate(theChange, changedObject, changedBy, dependencySpace);
- } // TCell::DoUpdate
-
-
- //----------------------------------------------------------------------------------------
- // TCell::GetNoOfDependentCells:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
- ArrayIndex TCell::GetNoOfDependentCells()
-
- {
- ArrayIndex count = 0;
- CDependentCellIterator iter(this);
-
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- count = count + 1;
- }
-
- return count;
- } // TCell::GetNoOfDependentCells
-
-
- //----------------------------------------------------------------------------------------
- // TCell::GetNoOfReferencedCells:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
- ArrayIndex TCell::GetNoOfReferencedCells()
-
- {
- ArrayIndex count = 0;
- CReferencedCellIterator iter(this);
-
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- count = count + 1;
- }
-
- return count;
- } // TCell::GetNoOfReferencedCells
-
-
- //----------------------------------------------------------------------------------------
- // TCell::AddDependentCell:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::AddDependentCell(TCell* aCell)
- {
- this->AddDependent(aCell);
- } // TCell::AddDependentCell
-
-
- //----------------------------------------------------------------------------------------
- // TCell::RemoveDependentCell:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::RemoveDependentCell(TCell* aCell)
- {
- this->RemoveDependent(aCell);
- } // TCell::RemoveDependentCell
-
-
- //----------------------------------------------------------------------------------------
- // TCell::ValueToString: Fills fValueString with the CString representation of the cell's
- // value. The "general" format is complicated because we try to ensure that the CString
- // will fit within the cell's column width. Thus we have to figure out the appropriate
- // representation for the value.
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void TCell::ValueToString()
- {
- CStr255 aString;
- char aCString[255]; // a char* type with preallocated
- // space. Used for a temp value later;
- decform theFormat;
- decimal d;
- decimal aDecimal;
- short i;
- short len;
- short sigDigits;
- short leftDigits;
- short rightDigits;
- short width;
- short digitWidth;
- short dotWidth;
- short eWidth;
- short minusWidth;
- short plusWidth;
- TColumn * aColumn;
- ValueType aValueType;
-
-
- aColumn = fCalcDocument->GetColumn(fColumn);
-
- switch (aColumn->fFormat.fStyle)
- {
- case kGeneral:
- {
- SetTheFont(aColumn->fFormat.fFontNumber, aColumn->fFormat.fFontSize, aColumn->fFormat.fFontStyle);
- digitWidth = CharWidth('0');
- dotWidth = CharWidth('.');
- eWidth = CharWidth('e');
- minusWidth = CharWidth('-');
- plusWidth = CharWidth('+');
- width = fCalcDocument->fCellsView->GetColWidth(fColumn) - (kCellHBorder * 2);
-
- theFormat = gGeneralFormat;
- aValueType = fValue;
- num2dec(&theFormat, aValueType, &d);
- aString = *((CStr255 *)(&d.sig));// sig is actually a CString, and we want it!
-
- len = aString.Length();
-
- if (d.sgn == 1)
- width = width - minusWidth;
-
- if (d.exp > 0)
- // We've exceeded the precision of our value representation
- {
- theFormat.style = FLOATDECIMAL;
- // account for '.' and '+e99'
- width = width - dotWidth - CharWidth('+') - eWidth - digitWidth - digitWidth;
- theFormat.digits = Min(kValuePrecision, width / digitWidth);
- }
- else
- {
-
- // determine number of significant digits
- sigDigits = 1; // in case all digits are zero
- for (i = len; i >= 2; i--) // this was DOWNTO
- if (aString[i] != '0')
- {
- sigDigits = i;
- break;
- }
-
- leftDigits = kValuePrecision + d.exp;
- rightDigits = sigDigits - leftDigits;
-
- if (leftDigits < sigDigits)
- width = width - dotWidth;// account for decimal CPoint
-
- if (leftDigits * digitWidth > width)
- {
- // We must convert to scientific notation
-
- // account for decimal CPoint and 'e9'
- width = width - dotWidth - eWidth - digitWidth;
-
- /* For positive numbers, SANE puts a space (' ') before
- the first significant digit. */
- if (d.sgn != 1)
- width = width - CharWidth(' ');
- if (d.exp < -kValuePrecision)
- width = width - minusWidth;
- else
- width = width - plusWidth;
- if (leftDigits > 10)
- width = width - digitWidth;// account for double-digit exponents
-
- theFormat.style = FLOATDECIMAL;
- theFormat.digits = Min(sigDigits, width / digitWidth);
- }
- else
- {
- theFormat.style = FIXEDDECIMAL;
- theFormat.digits = Min((width - (leftDigits * digitWidth) - dotWidth) / digitWidth, rightDigits);
- if (theFormat.digits < 0)
- theFormat.digits = 0;
- }
- }
- break;
- }
- case kDecimalStyle:
- {
- theFormat = gDecimalFormat;
- break;
- }
- case kNoDecimal:
- {
- theFormat = gNoDecimalFormat;
- break;
- }
- case kScientific:
- {
- theFormat = gScientificFormat;
- break;
- }
- } // switch!
-
- aValueType = fValue;
- num2dec(&theFormat, aValueType, &aDecimal);
- dec2str(&theFormat, &aDecimal, aCString);
- aString = aCString;
- // That should have been "Num2Str(theFormat, aValueType, (decstr)(aString));"
- if (aString[1] == ' ')
- aString.Delete(1, 1); // Remove leading space
- fValueString = aString.Copy(1, Min(kMaxValueLength, aString.Length()));
- } // TCell::ValueToString
-
-
- //----------------------------------------------------------------------------------------
- // TCell::GetDiskSize:
- //----------------------------------------------------------------------------------------
- #pragma segment AWriteFile
-
- short TCell::GetDiskSize(Boolean infoRecordOnly)
-
- {
- short cellSize;
-
-
- cellSize = sizeof(CellDiskInfo) - sizeof(CStr255) + fFormula.Length() + 1;
- if (!infoRecordOnly)
- cellSize = cellSize + (short)(this->GetNoOfReferencedCells() + this->GetNoOfDependentCells() + 1) * sizeof(CPoint);
- return cellSize;
- } // TCell::GetDiskSize
-
-
- //----------------------------------------------------------------------------------------
- // TCell::ReadFromDisk:
- //----------------------------------------------------------------------------------------
- #pragma segment AReadFile
-
- void TCell::ReadFromDisk(TFile* aFile)
- {
- CellDiskInfo cellInfo;
- TCell * referencedCell;
- RowNumber refRow;
- ColumnNumber refColumn;
- short refIndex;
- long count;
- short cellLength;
-
- count = sizeof(cellLength);
- FailOSErr(aFile->ReadData(&cellLength, count));
- count = cellLength;
- FailOSErr(aFile->ReadData(&cellInfo, count));
-
- fKind = cellInfo.kind;
- fError = cellInfo.error;
- fValue = cellInfo.value;
- fFormula = cellInfo.formula;
-
- for (refIndex = 1; refIndex <= cellInfo.noOfReferences; refIndex++)
- {
- ReadCellCoordinate(aFile, refRow, refColumn);
- referencedCell = fCalcDocument->GetCell(refRow, refColumn);
- referencedCell->AddDependentCell(this);
- }
- } // TCell::ReadFromDisk
-
-
- //----------------------------------------------------------------------------------------
- // TCell::WriteToDisk:
- //----------------------------------------------------------------------------------------
- #pragma segment AWriteFile
-
- void TCell::WriteToDisk(TFile* aFile)
- {
- CellDiskInfo cellInfo;
- long count;
- short cellLength;
-
- // write out the data that TCalcDocument.DoRead expects to see
- this->WriteCellCoordinateToDisk(aFile);
-
- cellLength = this->GetDiskSize(TRUE);
- count = sizeof(cellLength);
- FailOSErr(aFile->WriteData(&cellLength, count));
-
- // write out the data that TCell.ReadFromDisk expects to see
- cellInfo.kind = fKind;
- cellInfo.error = fError;
- cellInfo.value = fValue;
- cellInfo.noOfReferences = (short)this->GetNoOfReferencedCells();
- cellInfo.formula = fFormula;
- count = cellLength;
- FailOSErr(aFile->WriteData(&cellInfo, count));
-
- CReferencedCellIterator iter(this);
-
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- aCell->WriteCellCoordinateToDisk(aFile);
- } // TCell::WriteToDisk
-
-
- //----------------------------------------------------------------------------------------
- // TCell::WriteCellCoordinateToDisk:
- //----------------------------------------------------------------------------------------
- #pragma segment AWriteFile
-
- void TCell::WriteCellCoordinateToDisk(TFile* aFile)
- {
- CPoint cellCoordinate;
- long count;
-
- cellCoordinate.v = this->fRow;
- cellCoordinate.h = this->fColumn;
- count = sizeof(CPoint);
- FailOSErr(aFile->WriteData(&cellCoordinate, count));
- } // TCell::WriteCellCoordinateToDisk
-
-
- //----------------------------------------------------------------------------------------
- // TCell::ReadFromScrap:
- //----------------------------------------------------------------------------------------
- #pragma segment AClipBoard
-
- void TCell::ReadFromScrap(Handle theScrap, long& scrapOffset)
-
- {
- short cellLength;
- CellDiskInfo cellInfo;
- TCell * referencedCell;
- CPoint cellCoord;
- short refIndex;
-
-
- ReadScrap(theScrap, scrapOffset, (unsigned char*) & cellLength, sizeof(cellLength));
- ReadScrap(theScrap, scrapOffset, (unsigned char*) & cellInfo, cellLength);
-
- fKind = cellInfo.kind;
- fError = cellInfo.error;
- fValue = cellInfo.value;
- fFormula = cellInfo.formula;
-
- for (refIndex = 1; refIndex <= cellInfo.noOfReferences; refIndex++)
- {
- ReadScrap(theScrap, scrapOffset, (unsigned char*) & cellCoord, sizeof(cellCoord));
- referencedCell = fCalcDocument->GetCell(cellCoord.v, cellCoord.h);
- referencedCell->AddDependentCell(this);
- }
- } // TCell::ReadFromScrap
-
-
- //----------------------------------------------------------------------------------------
- // TCell::WriteToScrap:
- //----------------------------------------------------------------------------------------
- #pragma segment AClipBoard
-
- void TCell::WriteToScrap(Handle theScrap, long& scrapOffset)
-
- {
- CellDiskInfo cellInfo;
- short cellLength;
- CPoint cellCoordinate;
-
-
- cellCoordinate.v = this->fRow;
- cellCoordinate.h = this->fColumn;
- WriteScrap(theScrap, scrapOffset, (unsigned char*) & cellCoordinate, sizeof(cellCoordinate));
-
- cellLength = GetDiskSize(TRUE); // don't include ref's && dependents
- WriteScrap(theScrap, scrapOffset, (unsigned char*) & cellLength, sizeof(cellLength));
- cellInfo.kind = fKind;
- cellInfo.error = fError;
- cellInfo.value = fValue;
- cellInfo.noOfReferences = 0;
- cellInfo.formula = fFormula;
-
- WriteScrap(theScrap, scrapOffset, (unsigned char*) & cellInfo, cellLength);
- } // TCell::WriteToScrap
-
-
- //========================================================================================
- // CLASS TCellEditCommand
- //========================================================================================
- #undef Inherited
- #define Inherited TCommand
-
- #pragma segment ClassDescRes
- MA_DEFINE_CLASS_M1(TCellEditCommand, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::ICellEditCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment ASelCommand
-
- void TCellEditCommand::ICellEditCommand(TCalcDocument* itsDocument,
- CommandNumber itsCommand)
-
- {
- this->ICommand(itsCommand, itsDocument, kCanUndo, kCausesChange, itsDocument);
- FailInfo fi;
- Try(fi)
- {
- fCalcDocument = itsDocument;
- fSelection = MakeNewRgn(); // copy the current selection region
- CopyRgn(itsDocument->fCellsView->fSelections, fSelection);
- fChangesClipboard = itsCommand != cClear;
- fCausesChange = itsCommand != cCopy;
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- } // TCellEditCommand::ICellEditCommand
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- TCellEditCommand::~TCellEditCommand() // override
-
- {
- fSelection = DisposeIfRgnHandle(fSelection);
- } // TCellEditCommand::Free
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::DoIt:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::DoIt()
-
- {
- if (fIdentifier != cClear)
- this->CopySelection();
- if (fIdentifier != cCopy)
- this->DeleteSelection();
- } // TCellEditCommand::DoIt
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::UndoIt: If the user has changed the selection since this command was
- // created, restore it before Undoing so that the correct cells are affected.
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::UndoIt()
- {
- if (fIdentifier != cCopy)
- {
- this->ReSelect(); // restore command's original selection
- this->RestoreSelection();
- fCalcDocument->fCellsView->ScrollSelectionIntoView(TRUE);
- }
- } // TCellEditCommand::UndoIt
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::RedoIt: If the user has changed the selection since this command was
- // created, restore it before Redoing so that the correct cells are affected.
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::RedoIt()
- {
- if (fIdentifier != cCopy)
- {
- this->ReSelect(); // restore command's original selection
- this->DeleteSelection();
- fCalcDocument->fCellsView->ScrollSelectionIntoView(TRUE);
- }
- } // TCellEditCommand::RedoIt
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::Commit:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::Commit()
-
- {
- fCalcDocument->FreeDeletedCells();
- } // TCellEditCommand::Commit
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::CopySelection:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::CopySelection()
-
- {
- TCalcDocument * clipDocument;
- TCellsView * clipView;
- CRect clipRect;
-
- clipDocument = new TCalcDocument;
- clipRect = (*fSelection)->rgnBBox;
- clipRect.bottom = clipRect.bottom - 1;
- clipRect.right = clipRect.right - 1;
- clipDocument->ICalcDocument(NULL, clipRect);
- clipDocument->DoInitialState();
-
- {
- CSelectedCellIterator iter(fCalcDocument->fRowsView);
- for (GridCell aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- TRow * newRow;
-
-
- newRow = (TRow *)(fCalcDocument->GetRow(aCell.v)->Clone());
- newRow->fNumber = newRow->fNumber - clipDocument->fRowOffset;
- clipDocument->AddRow(newRow);
- }
- }
-
- {
- CSelectedCellIterator iter(fCalcDocument->fColumnsView);
- for (GridCell aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- TColumn * newColumn;
-
-
- newColumn = (TColumn *)(fCalcDocument->GetColumn(aCell.h)->Clone());
- newColumn->fNumber = newColumn->fNumber - clipDocument->fColumnOffset;
- clipDocument->AddColumn(newColumn);
- }
- }
-
- {
- CSelectedExistingCalcCellIterator iter(fCalcDocument);
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- TCell * newCell;
- newCell = (TCell *)(aCell->Clone());
- clipDocument->AddCell(newCell, newCell->fRow - clipDocument->fRowOffset, newCell->fColumn - clipDocument->fColumnOffset);
- }
- }
-
- clipView = new TCellsView;
- clipView->ICellsView(clipDocument, TRUE, NULL);
- clipDocument->fCellsView = clipView;
- this->ClaimClipboard(clipView);
- clipView->AdjustFrame();
- } // TCellEditCommand::CopySelection
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::DeleteSelection:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::DeleteSelection()
- {
- CSelectedExistingCalcCellIterator iter(fCalcDocument);
-
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- fCalcDocument->DeleteCell(aCell->fRow, aCell->fColumn);
- }
-
- fCalcDocument->DoRecalculate(!kForceAutomatic, !kUpdateDependencies);
- fCalcDocument->fCellsView->InvalidateSelection();
- } // TCellEditCommand::DeleteSelection
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::RestoreSelection:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::RestoreSelection()
-
- {
- GridCell firstCell;
- CSelectedExistingCalcCellIterator iter(fCalcDocument);
-
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- fCalcDocument->UndeleteCell(aCell->fRow, aCell->fColumn);
- }
-
- fCalcDocument->DoRecalculate(!kForceAutomatic, !kUpdateDependencies);
- fCalcDocument->fCellsView->InvalidateSelection();
-
- firstCell = fCalcDocument->fCellsView->FirstSelectedCell();
- fCalcDocument->SetEntry(firstCell.v, firstCell.h);// update entry view
- } // TCellEditCommand::RestoreSelection
-
-
- //----------------------------------------------------------------------------------------
- // TCellEditCommand::ReSelect:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellEditCommand::ReSelect()
-
- {
- fCalcDocument->fCellsView->ReSelect(fSelection);
- } // TCellEditCommand::ReSelect
-
-
- //========================================================================================
- // CLASS TCellPasteCommand
- //========================================================================================
- #undef Inherited
- #define Inherited TCommand
-
- #pragma segment ClassDescRes
- MA_DEFINE_CLASS_M1(TCellPasteCommand, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TCellPasteCommand::ICellPasteCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment ASelCommand
-
- void TCellPasteCommand::ICellPasteCommand(TCalcDocument* itsDocument)
- {
- #if qDebug
- if (!(gClipboardMgr->fClipView->DescendsFrom(TCellsView::GetClassDescStatic())))
- ProgramBreak("Attempt to paste a non-TCellsView clipboard");
- #endif
-
- this->ICommand(cPaste, itsDocument, kCanUndo, kCausesChange, itsDocument);
-
- FailInfo fi;
- Try(fi)
- {
- fCalcDocument = itsDocument;
- fSelection = MakeNewRgn(); // copy the current selection region
- CopyRgn(itsDocument->fCellsView->fSelections, fSelection);
- fClipDocument = ((TCellsView *)(gClipboardMgr->fClipView))->fCalcDocument;
- fReplacedCells = (TCellList *)NewList();
- #if qDebug
- fReplacedCells->SetEltType("TCell");
- #endif
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- } // TCellPasteCommand::ICellPasteCommand
-
-
- //----------------------------------------------------------------------------------------
- // TCellPasteCommand::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- TCellPasteCommand::~TCellPasteCommand() // override
-
- {
- fSelection = DisposeIfRgnHandle(fSelection);
-
- fReplacedCells = (TCellList *)(FreeListIfObject(fReplacedCells));
- } // TCellPasteCommand::Free
-
-
- //----------------------------------------------------------------------------------------
- // TCellPasteCommand::DoIt:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellPasteCommand::DoIt()
- {
- FailInfo fi;
-
- Try(fi)
- {
- short r = 1;
- short c = 1;
-
- // Extra block to ensure that Success is called in the proper order
- {
- CSelectedCellIterator iter(fCalcDocument->fCellsView);
-
- for (GridCell aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- TCell* sourceCell;
- TCell* replacedCell;
- TCell* destCell;
-
- destCell = fCalcDocument->GetCell(aCell.v, aCell.h);
- replacedCell = (TCell *)(destCell->Clone());
- fReplacedCells->InsertLast(replacedCell);
-
- sourceCell = fClipDocument->GetCell(r, c);
- ++c;
- if (c > fClipDocument->fNoOfColumns)
- {
- c = 1;
- ++r;
- if (r > fClipDocument->fNoOfRows)
- r = 1;
- }
- destCell->CopyContents(sourceCell); // copy the necessary fields
- }
- }
- fi.Success();
- }
- else
- {
- // Extra block to ensure that ReSignal is called in the proper order
- {
- CCalcCellIterator iter(fReplacedCells);
-
- for (TCell * aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- TCell* pastedCell;
-
- pastedCell = fCalcDocument->GetCell(aCell->fRow, aCell->fColumn);
- if (aCell->IsEmpty()) // free up memory used by empty cell
- {
- fCalcDocument->DeleteCell(pastedCell->fRow, pastedCell->fColumn);
- fCalcDocument->FreeCell(pastedCell);
- }
- else
- pastedCell->CopyContents(aCell);
- }
- }
- fReplacedCells->FreeAll();
- this->UpdateViews();
- fi.ReSignal();
- }
-
- this->UpdateViews();
- } // TCellPasteCommand::DoIt
-
-
- //----------------------------------------------------------------------------------------
- // TCellPasteCommand::UndoIt:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellPasteCommand::UndoIt()
- {
- CCalcCellIterator iter(fReplacedCells);
-
- fCalcDocument->fCellsView->ReSelect(fSelection);// restore original selection
- for (TCell * replacedCell = iter.FirstCell(); iter.More(); replacedCell = iter.NextCell())
- {
- TCell * pastedCell;
-
- pastedCell = fCalcDocument->GetCell(replacedCell->fRow, replacedCell->fColumn);
- pastedCell->CopyContents(replacedCell);
- }
- this->UpdateViews();
- } // TCellPasteCommand::UndoIt
-
-
- //----------------------------------------------------------------------------------------
- // TCellPasteCommand::RedoIt:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellPasteCommand::RedoIt()
- {
- short r = 1;
- short c = 1;
-
- fCalcDocument->fCellsView->ReSelect(fSelection);// restore original selection
-
- CSelectedCellIterator iter(fCalcDocument->fCellsView);
-
- for (GridCell aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell())
- {
- TCell * sourceCell;
- TCell * destCell;
-
- destCell = fCalcDocument->GetCell(aCell.v, aCell.h);
- sourceCell = fClipDocument->GetCell(r, c);
- ++c;
- if (c > fClipDocument->fNoOfColumns)
- {
- c = 1;
- ++r;
- if (r > fClipDocument->fNoOfRows)
- r = 1;
- }
-
- destCell->CopyContents(sourceCell); // copy the necessary fields
- }
- this->UpdateViews();
- } // TCellPasteCommand::RedoIt
-
-
- //----------------------------------------------------------------------------------------
- // TCellPasteCommand::UpdateViews:
- //----------------------------------------------------------------------------------------
- #pragma segment ADoCommand
-
- void TCellPasteCommand::UpdateViews()
-
- {
- CStr255 aString;
- GridCell aCell;
-
- fCalcDocument->DoRecalculate(!kForceAutomatic, kUpdateDependencies);
- fCalcDocument->fCellsView->InvalidateSelection();
-
- aCell.h = fCalcDocument->fEditColumn;
- aCell.v = fCalcDocument->fEditRow;
- if (fCalcDocument->fCellsView->IsCellSelected(aCell))
- {
- fCalcDocument->fEditCell = fCalcDocument->GetCell(aCell.v, aCell.h);
- fCalcDocument->fEditCell->GetAsString(aString);
- fCalcDocument->fEntryView->SetToString(aString);
- }
- } // TCellPasteCommand::UpdateViews
-
-
-
- //========================================================================================
- // CLASS CCalcCellIterator
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CCalcCellIterator::CCalcCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CCalcCellIterator::CCalcCellIterator(TCalcDocument* theCalcDocument) :
- CObjectIterator(theCalcDocument ? theCalcDocument->fCells : NULL)
- {
- } // CCalcCellIterator::CCalcCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CCalcCellIterator::CCalcCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CCalcCellIterator::CCalcCellIterator(TCellList* theCellList) :
- CObjectIterator(theCellList)
- {
- } // CCalcCellIterator::CCalcCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CCalcCellIterator::~CCalcCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CCalcCellIterator::~CCalcCellIterator()
- {
- } // CCalcCellIterator::~CCalcCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CCalcCellIterator::CurrentCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CCalcCellIterator::CurrentCell()
- {
- // returns the current Cell
- return (TCell *)this->CurrentObject();
- } // CCalcCellIterator::CurrentCell
-
-
- //----------------------------------------------------------------------------------------
- // CCalcCellIterator::FirstCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CCalcCellIterator::FirstCell()
- {
- // return the first Cell in the iteration
- return (TCell *)this->FirstObject();
- } // CCalcCellIterator::FirstCell
-
-
- //----------------------------------------------------------------------------------------
- // CCalcCellIterator::NextCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CCalcCellIterator::NextCell()
- {
- // advances the iteration and then returns the Cell
- return (TCell *)this->NextObject();
- } // CCalcCellIterator::NextCell
-
-
- //========================================================================================
- // CLASS CSelectedExistingCalcCellIterator
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CSelectedExistingCalcCellIterator::CSelectedExistingCalcCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CSelectedExistingCalcCellIterator::CSelectedExistingCalcCellIterator(TCalcDocument* theCalcDocument) :
- CCalcCellIterator(theCalcDocument)
- {
- fSelectedRegion = theCalcDocument->fCellsView->fSelections;
- } // CSelectedExistingCalcCellIterator::CSelectedExistingCalcCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CSelectedExistingCalcCellIterator::~CSelectedExistingCalcCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CSelectedExistingCalcCellIterator::~CSelectedExistingCalcCellIterator()
- {
- } // CSelectedExistingCalcCellIterator::~CSelectedExistingCalcCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CSelectedExistingCalcCellIterator::Reset:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CSelectedExistingCalcCellIterator::Reset()
- {
- CArrayIterator::Reset(); // this should be Inherited::Reset,
- // but we can't since it's a C++ object.
- if (this->More() &&!this->IsCellSelected(CurrentCell())) // check that the first cell meets the
- // criteria for acceptance
- this->Advance(); // It doesn't, so we'll get the next
- // one, which is guaranteed to either
- // meet the criteria, or be NULL
- } // CSelectedExistingCalcCellIterator::Reset
-
-
- //----------------------------------------------------------------------------------------
- // CSelectedExistingCalcCellIterator::Advance:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CSelectedExistingCalcCellIterator::Advance()
- {
- CArrayIterator::Advance(); // this should be Inherited::Advance,
- // but we can't since it's a C++ object.
- while (this->More() &&!this->IsCellSelected(CurrentCell()))
- //while it doesn't meet the criteria…
- CArrayIterator::Advance(); // Get the next one.
- // (this should also be "inherited".)
- } // CSelectedExistingCalcCellIterator::Advance
-
-
- //----------------------------------------------------------------------------------------
- // CSelectedExistingCalcCellIterator::IsCellSelected:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Boolean CSelectedExistingCalcCellIterator::IsCellSelected(TCell* theCell)
-
- {
- if (this->More()) // is the cell valid??
- return PtInRgn(theCell->GetCoordinates(), fSelectedRegion); // is it selected?
- else
- return FALSE; // there is no cell, so it's
- // obviously not selected.
- } // CSelectedExistingCalcCellIterator::IsCellSelected
-
-
- //========================================================================================
- // CLASS CExistingCalcCellIterator
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CExistingCalcCellIterator::CExistingCalcCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CExistingCalcCellIterator::CExistingCalcCellIterator(TCalcDocument* theCalcDocument) :
- CCalcCellIterator(theCalcDocument)
-
- {
- fCalcDocument = theCalcDocument;
- } // CExistingCalcCellIterator::CExistingCalcCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CExistingCalcCellIterator::~CExistingCalcCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CExistingCalcCellIterator::~CExistingCalcCellIterator()
- {
- } // CExistingCalcCellIterator::~CExistingCalcCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CExistingCalcCellIterator::Reset:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CExistingCalcCellIterator::Reset()
- {
- CArrayIterator::Reset(); // this should be Inherited::Reset,
- // but we can't since it's a C++ object.
- // if you agree with me, please ask Bjarne
- // to change the standard.
-
- // now check that the first cell meets the criteria for acceptance
- if (this->More() &&!this->CellExists())
-
- this->Advance(); // It doesn't, so we'll get the next one,
- // which is guaranteed to either meet the
- // criteria, or be NULL
- } // CExistingCalcCellIterator::Reset
-
-
- //----------------------------------------------------------------------------------------
- // CExistingCalcCellIterator::CellExists:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Boolean CExistingCalcCellIterator::CellExists()
-
- {
- if (this->More()) // is the cell valid??
- {
- TCell * theCell = this->CurrentCell();
- return fCalcDocument->IsExistingCell(theCell); // is it selected?
- }
- else
- return FALSE; // there is no cell, so it's obviously
- // not selected.
- } // CExistingCalcCellIterator::CellExists
-
-
- //----------------------------------------------------------------------------------------
- // CExistingCalcCellIterator::Advance:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CExistingCalcCellIterator::Advance()
- {
- CArrayIterator::Advance(); // this should be Inherited::Advance,
- // but we can't since it's a C++ object.
- while (this->More() &&!this->CellExists())
- //while it doesn't meet the criteria…
- CArrayIterator::Advance(); // Get the next one.
- // (this should also be "inherited".)
- } // CExistingCalcCellIterator::Advance
-
-
- //========================================================================================
- // CLASS CReferencedCellIterator
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::CReferencedCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CReferencedCellIterator::CReferencedCellIterator(TCell* theCell) :
- CNotifierIterator(theCell,(TStandardDependencySpace*) theCell->GetDependencySpace())
- {
- } // CReferencedCellIterator::CReferencedCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::~CReferencedCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CReferencedCellIterator::~CReferencedCellIterator()
- {
- } // CReferencedCellIterator::~CReferencedCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::Reset:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CReferencedCellIterator::Reset()
- {
- CNotifierIterator::Reset(); // this should be Inherited::Reset,
- // but we can't since it's a C++ object.
-
- // now check that the first notifier is a cell
- if (this->More() &&!this->NotifierIsCell())
-
- this->Advance(); // It doesn't, so we'll get the next one,
- // which is guaranteed to either meet the
- // criteria, or be NULL
- } // CReferencedCellIterator::Reset
-
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::FirstCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CReferencedCellIterator::FirstCell()
- {
- return (TCell *)this->FirstNotifier();
- } // CReferencedCellIterator::FirstCell
-
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::CurrentCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CReferencedCellIterator::CurrentCell()
- {
- return (TCell *)this->CurrentNotifier();
- } // CReferencedCellIterator::CurrentCell
-
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::NextCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CReferencedCellIterator::NextCell()
- {
- return (TCell *)this->NextNotifier();
- } // CReferencedCellIterator::NextCell
-
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::NotifierIsCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Boolean CReferencedCellIterator::NotifierIsCell()
- {
- if (this->More()) // is the notifier valid??
- {
- TObject * theObject = this->CurrentNotifier();
- return theObject->DescendsFrom(TCell::GetClassDescStatic()); // is it a cell?
- }
- else
- return FALSE; // there is no notifier, so it's obviously
- // not a cell.
- } // CReferencedCellIterator::NotifierIsCell
-
-
- //----------------------------------------------------------------------------------------
- // CReferencedCellIterator::Advance:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CReferencedCellIterator::Advance()
- {
- CNotifierIterator::Advance(); // this should be Inherited::Advance, but
- // we can't since it's a C++ object.
- while (this->More() &&!this->NotifierIsCell()) // while it doesn't meet the criteria…
- CNotifierIterator::Advance(); // Get the next one. (this should also
- // be "inherited".)
- } // CReferencedCellIterator::Advance
-
-
- //========================================================================================
- // CLASS CDependentCellIterator
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::CDependentCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CDependentCellIterator::CDependentCellIterator(TCell* theCell) :
- CDependentIterator(theCell,(TStandardDependencySpace*) theCell->GetDependencySpace())
- {
- } // CDependentCellIterator::CDependentCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::~CDependentCellIterator:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CDependentCellIterator::~CDependentCellIterator()
- {
- } // CDependentCellIterator::~CDependentCellIterator
-
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::Reset:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CDependentCellIterator::Reset()
- {
- CDependentIterator::Reset(); // this should be Inherited::Reset, but
- // we can't since it's a C++ object.
-
- // now check that the first notifier is a cell
- if (this->More() &&!this->DependentIsCell())
- this->Advance(); // It isn't, so we'll get the next one,
- // which is guaranteed to either meet the
- // criteria, or be NULL
- } // CDependentCellIterator::Reset
-
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::FirstCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CDependentCellIterator::FirstCell()
- {
- return (TCell *)this->FirstDependent();
- } // CDependentCellIterator::FirstCell
-
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::CurrentCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CDependentCellIterator::CurrentCell()
- {
- return (TCell *)this->CurrentDependent();
- } // CDependentCellIterator::CurrentCell
-
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::NextCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TCell* CDependentCellIterator::NextCell()
- {
- return (TCell *)this->NextDependent();
- } // CDependentCellIterator::NextCell
-
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::DependentIsCell:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Boolean CDependentCellIterator::DependentIsCell()
- {
- if (this->More()) // is the dependent valid??
- {
- TObject * theObject = this->CurrentDependent();
- return theObject->DescendsFrom(TCell::GetClassDescStatic()); // is it a cell?
- }
- else
- return FALSE; // there is no dependent, so it's obviously not a cell.
- } // CDependentCellIterator::DependentIsCell
-
-
- //----------------------------------------------------------------------------------------
- // CDependentCellIterator::Advance:
- //----------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CDependentCellIterator::Advance()
- {
- CDependentIterator::Advance(); // this should be Inherited::Advance,
- // but we can't since it's a C++ object.
- while (this->More() &&!this->DependentIsCell()) // while it doesn't meet the criteria…
- CDependentIterator::Advance(); // Get the next one. (this should also
- // be "inherited".)
- } // CDependentCellIterator::Advance
-
- //========================================================================================
- // CLASS CParseSubscribedText
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CParseSubscribedText::CParseSubscribedText:
- //----------------------------------------------------------------------------------------
- #pragma segment ANonRes
-
- CParseSubscribedText::CParseSubscribedText(TDesignator* aDesignator,
- TStream* aStream,
- long length,
- CRect aSubBounds, // bounds of the subscriber
- CRect aPubBounds) // bounds of the publisher
- {
- theDesignator = aDesignator;
- theStream = aStream;
- theLength = length;
- subBounds = aSubBounds;
- pubBounds = aPubBounds;
- } // CParseSubscribedText::CParseSubscribedText
-
-
- //----------------------------------------------------------------------------------------
- // CParseSubscribedText::ParseSubscribedText:
- //----------------------------------------------------------------------------------------
- #pragma segment ANonRes
- // same as its caller DoReadTEXT
-
- CStr255 CParseSubscribedText::ParseSubscribedText(Handle textHdl, GridCell aGridCell)
-
- {
- short i; // just an ordinary index.
- CStr255 ParseSubscribedTextResult; // the temporary of the return result
-
- theText = textHdl;
- if (theLength == 0)
- {
- return ParseSubscribedTextResult;
- }
- else
- {
- normalizedCell.v = aGridCell.v - subBounds.top;
- normalizedCell.h = aGridCell.h - subBounds.left;
- offset = 0;
-
- // skip over returns
- for (i = 1; i <= normalizedCell.v; i++)
- {
- this->ScanTo(chReturn);
- offset = offset + 1; // skip over return
- if (offset > theLength) // there's no more input
- return ParseSubscribedTextResult;
- }
-
- // is there a relevant data item to read in?
- if (this->NumTabs() < normalizedCell.h)
- return ParseSubscribedTextResult;
-
- // skip over tabs
- for (i = 1; i <= normalizedCell.h; i++)
- {
- this->ScanTo(chTab);
- offset = offset + 1; // skip over tab
- if (offset > theLength) // there's no more input
- return ParseSubscribedTextResult;
- }
-
- p = (unsigned char*)(*theText) + offset; // set where to start
- maxLength = Min(theLength - offset, 255);
- offset = 0;
- aChar = *(p + offset); // get the "offset"th character
-
- ParseSubscribedTextResult = "";
-
- while (((offset < maxLength) && (aChar != chTab) && (aChar != chReturn)))
- {
- offset = offset + 1;
- ParseSubscribedTextResult += aChar; // save the current character
- aChar = *(p + offset); // get the next one
- }
- return ParseSubscribedTextResult;
- }
- } // CParseSubscribedText::ParseSubscribedText
-
-
- //----------------------------------------------------------------------------------------
- // CParseSubscribedText::ScanTo:
- //----------------------------------------------------------------------------------------
- #pragma segment ANonRes
-
- void CParseSubscribedText::ScanTo(char ch)
-
- {
- unsigned char* p;
-
-
- p = (unsigned char*)(*theText) + offset;
- while ((*p != ch) && (offset < theLength))
- {
- offset = offset + 1;
- p = (unsigned char*)(*theText) + offset;
- }
- } // CParseSubscribedText::ScanTo
-
-
- //----------------------------------------------------------------------------------------
- // CParseSubscribedText::NumTabs:
- //----------------------------------------------------------------------------------------
- #pragma segment ANonRes
-
- short CParseSubscribedText::NumTabs()
- // number of tabs between *theText + localOffset and the next chReturn
-
- {
- unsigned char* p;
- long localOffset;
- short num;
-
-
- localOffset = offset;
- num = 0;
- p = (unsigned char*)(*theText) + localOffset;
- while ((*p != chReturn) && (localOffset < theLength))
- {
- if (*p == chTab)
- num = num + 1;
- localOffset = localOffset + 1;
- p = (unsigned char*)(*theText) + localOffset;
- }
- return num;
- } // CParseSubscribedText::NumTabs
-
-
- //========================================================================================
- // CLASS CCellParser
- //========================================================================================
- #undef Inherited
-
- //----------------------------------------------------------------------------------------
- // CCellParser::CCellParser:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
- // same as its callers TCell:DoUpdate and TCell::Recalculate
-
- CCellParser::CCellParser(TCell* theCell)
- {
- fCell = theCell;
- fCalcDocument = fCell->fCalcDocument;
- } // CCellParser::CCellParser
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::GetNextChar:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
- void CCellParser::GetNextChar()
-
- {
- do
- {
- if (formulaIndex < formulaLength)
- {
- ++formulaIndex;
- theChar = fFormula[formulaIndex]; // get the "formulaIndex"th character of fFormula
- }
- else
- theChar = 0;
-
- } while (theChar == ' ');
- if ((theChar >= 'a') && (theChar <= 'z'))
- theChar = theChar - 32;
- } // CCellParser::GetNextChar
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::DoInteger:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- EvalResult CCellParser::DoInteger(short& theInteger)
- {
- theInteger = 0;
- while (IsDigit(theChar))
- {
- theInteger = theInteger * 10 + theChar - '0';
- this->GetNextChar();
- }
- return kNoError;
- } // CCellParser::DoInteger
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::DoNumber:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- EvalResult CCellParser::DoNumber(ValueType& theValue)
-
- {
- // DoNumber is called only when theChar is a numeric digit or a decimal CPoint
- short newIndex;
- decimal decimalNumber;
- short IsValidNumber = FALSE; // this is because it is passed in as a
- // reference in str2dec and str2dec's
- // interface is dumb and requires a
- // reference to a short.
- Boolean startsWithDecPt;
-
-
- startsWithDecPt = (theChar == '.');
- newIndex = formulaIndex -1;
-
- str2dec((const char*)fFormula, &newIndex, &decimalNumber, &IsValidNumber);
- // Str2Dec returns IsValidNumber == false if the digits are followed by non-numerics like *
-
- if (startsWithDecPt && (!IsValidNumber))
- {
- this->GetNextChar();
- if (!IsDigit(theChar))
- return kBadNumber;
- }
- formulaIndex = newIndex;
- this->GetNextChar();
- theValue = dec2num(&decimalNumber);
- return kNoError;
- } // CCellParser::DoNumber
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::DoCellReference:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- EvalResult CCellParser::DoCellReference(ValueType& theValue)
-
- {
- EvalResult theResult;
- short r; // Can't use RowNumber because it may be
- short c; // …out of range
- TCell * referencedCell;
- CRect aRect;
-
- theResult = kNoError;
- aRect = fCalcDocument->fDimensions; // valid coordinates
- c = 0;
- while ((theChar >= 'A') && (theChar <= 'Z') && (c <= aRect.right))
- {
- c = c * 26 + theChar - 'A' + 1;
- this->GetNextChar();
- }
- if (c > aRect.right) // column is out of range, so
- r = 0; // …don't bother looking for row number
- else
- theResult = this->DoInteger(r);
- if (fCalcDocument->CellInRange(r, c, aRect))
- {
- referencedCell = fCalcDocument->GetExistingCell(r - fCalcDocument->fRowOffset, c - fCalcDocument->fColumnOffset);
- if (referencedCell == NULL) // cell doesn't exist
- theValue = 0;
- else
- {
- if (referencedCell->fEvaluating)
- theResult = kSelfReference;
- else if (referencedCell->fKind == kErrorCell)
- theResult = kErrorCellReference;
- else if (referencedCell->fKind == kTextCell)
- theValue = 0;
- else
- theValue = referencedCell->fValue;
-
- if (updateDependencies && /*!!!RCR*/(theResult != kSelfReference))
- {
- referencedCell->AddDependentCell(fCell);
- }
- }
- }
- else
- theResult = kBadCellReference;
- return theResult;
- } // CCellParser::DoCellReference
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::Term:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- EvalResult CCellParser::Term(ValueType& theValue)
-
- {
- EvalResult theTempResult;
-
- if (theChar == '(')
- {
- this->GetNextChar();
- theTempResult = this->Expression(theValue);
- if (theChar == ')')
- this->GetNextChar();
- else
- theTempResult = kMissingRightParen;
- }
- else if (IsDigit(theChar) || (theChar == '.'))
- theTempResult = this->DoNumber(theValue);
- else if ((theChar >= 'A') && (theChar <= 'Z'))
- theTempResult = this->DoCellReference(theValue);
- else if (theChar == '+')
- {
- this->GetNextChar();
- theTempResult = this->Term(theValue);
- }
- else if (theChar == '-')
- {
- this->GetNextChar();
- theTempResult = this->Term(theValue);
- theValue = -theValue;
- }
- else
- theTempResult = kIllegalCharacter;
- return theTempResult;
- } // CCellParser::Term
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::Factor:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- EvalResult CCellParser::Factor(ValueType& theValue)
-
- {
- EvalResult theResult;
- ValueType factorValue;
-
-
- theResult = this->Term(theValue);
- if (theResult == kNoError)
- if (theChar == '*')
- {
- this->GetNextChar();
- theResult = this->Factor(factorValue);
- theValue = theValue * factorValue;
- }
- else if (theChar == '/')
- {
- this->GetNextChar();
- theResult = this->Factor(factorValue);
- theValue = theValue / factorValue;
- }
- return theResult;
- } // CCellParser::Factor
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::Expression:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- EvalResult CCellParser::Expression(ValueType& theValue)
-
- {
- EvalResult factorResult;
- ValueType factorValue;
-
-
- factorResult = this->Factor(theValue);
- if (factorResult == kNoError)
- do
- {
- if (theChar == '+')
- {
- this->GetNextChar();
- factorResult = this->Factor(factorValue);
- theValue = theValue + factorValue;
- }
- else if (theChar == '-')
- {
- this->GetNextChar();
- factorResult = this->Factor(factorValue);
- theValue = theValue - factorValue;
- }
- } while ((theChar == '+') || (theChar == '-'));
- return factorResult;
- } // CCellParser::Expression
-
-
- //----------------------------------------------------------------------------------------
- // CCellParser::EvaluateFormula:
- //----------------------------------------------------------------------------------------
- #pragma segment ARes
-
- void CCellParser::EvaluateFormula(KindOfCell& theKind,
- EvalResult& theError,
- ValueType& theValue,
- CStr255& theFormula,
- Boolean doUpdateDependencies)
- {
- fFormula = theFormula;
- updateDependencies = doUpdateDependencies;
- formulaLength = fFormula.Length();
- formulaIndex = 0;
- this->GetNextChar();
-
- if (IsDigit(theChar) || (theChar == '=') || (theChar == '-') || (theChar == '+') || (theChar == '.'))
- {
- if (theChar == '=')
- this->GetNextChar();
-
- theError = this->Expression(theValue);
-
- if (theError == kNoError)
- {
- if ((formulaIndex <= formulaLength) && (theChar != 0))
- theError = kGarbageAtEnd;
- }
- if (theError == kNoError)
- theKind = kValueCell;
- else
- theKind = kErrorCell;
- }
- else
- theKind = kTextCell;
- } // CCellParser::EvaluateFormula
-
- //----------------------------------------------------------------------------------------
- // End of UCalcCells.cp
-
- #pragma segment Inline
-